﻿#include "frommain.h"
#include "ui_frommain.h"
#include "imghelper.h"
#include <QFile>
#include <QImage>
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include <QMimeData>
FromMain::FromMain(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::FromMain)
{
    ui->setupUi(this);

    setAcceptDrops(true);

    ui->widgetSet->setVisible(false);
    ui->wB->setVisible(false);
    ui->wR->setVisible(false);
    ui->wG->setVisible(false);
    ui->btnLoad->setVisible(false);
    ui->btnYuvToRgb->setVisible(false);
}

FromMain::~FromMain()
{
    delete ui;
}

void FromMain::showImg(const QString &in_filePath)
{
    QString fileName = in_filePath.split("/").last();
    QStringList fileInfo = fileName.split(".");
    QStringList fileNameInfo = fileInfo.first().split("_");
    QString format = fileInfo.last();

    QImage img(in_filePath);
    if(!img.isNull())
    {
        m_img = img.copy();
        ui->wSrc->setImg(m_img);
        return;
    }

    if(!fileName.contains("x"))
    {
        QMessageBox::information(this,"提示","请手动设置分辨率");
        ui->widgetSet->setVisible(true);
        return;
    }

    int width =0;
    int height = 0;
    for(int i=0;i<fileNameInfo.size();++i)
    {
        QString tmp = fileNameInfo[i];
        if(tmp.contains("x") || tmp.contains("X"))
        {
            width = tmp.split("x").first().toInt();
            height = tmp.split("x").last().toInt();
            break;
        }
    }
    selectFormt(in_filePath,width,height,format);

}

void FromMain::selectFormt(const QString &in_filePath, int width, int height,const QString &format)
{
    if(format == "rgb")
    {
        QByteArray imgArr = imgHelper::getImgFromFile(in_filePath);
        QImage img(reinterpret_cast<unsigned char*>(imgArr.data()),width,height,width*3,QImage::Format_RGB888);
        m_img = img.copy();
        ui->wSrc->setImg(m_img);
    }
    else if(format == "yuv")
    {
        QByteArray imgArr = imgHelper::getImgFromFile(in_filePath);

        QVector<unsigned char> imgVector =  imgHelper::yuv420pToRGB24(reinterpret_cast<const unsigned char*>(imgArr.data()),width,height);
        QImage img(imgVector.data(),width,height,width*3,QImage::Format_RGB888);
        m_img = img.copy();
        ui->wSrc->setImg(m_img);
    }
    else if(format=="r"||format=="g"||format=="b"||format=="y"||format=="u"||format=="v")
    {
        QByteArray imgArr = imgHelper::getImgFromFile(in_filePath);
        QImage img(reinterpret_cast<const unsigned char*>(imgArr.data()),width,height,width,QImage::Format_Grayscale8);
        m_img = img.copy();
        ui->wSrc->setImg(m_img);
    }
    else
    {
        QMessageBox::information(this,"提示",QString("不支持(*.%1)格式").arg(format));
        ui->widgetSet->setVisible(true);
        return;
    }
}

void FromMain::on_btnLoad_clicked()
{
   QByteArray imgArr = imgHelper::getImgFromFile("cie1931_500x500.rgb");
   QImage img(reinterpret_cast<unsigned char*>(imgArr.data()),500,500,500*3,QImage::Format_RGB888);
   m_img = img.copy();
   ui->wSrc->setImg(m_img);
}

void FromMain::on_btnSplit_clicked()
{
    if(m_img.isNull())
        return;

    ui->wB->setVisible(true);
    ui->wR->setVisible(true);
    ui->wG->setVisible(true);

    int height = m_img.height();
    int width = m_img.width();
    m_img = m_img.convertToFormat(QImage::Format_RGB888);
    //1.转成成unsigned char*
    unsigned char * imgChar = new unsigned char[height*width*3];
    std::fill_n(imgChar,height*width*3,0);
    for(int i = 0;i<height;i++)
    {
        memcpy(imgChar+i*width*3,m_img.scanLine(i),width*3);
    }
    QVector<QVector<unsigned char>> rgbs = imgHelper::rgbSplit(imgChar,width,height);
    //imgHelper::saveRGBChannelsToFiles(rgbs,width,height);
    //这里应该执行的是浅拷贝rgb被释放后，内存就消失了
    QImage rImg(rgbs[0].data(), width, height, width, QImage::Format_Grayscale8);
    QImage gImg(rgbs[1].data(), width, height, width, QImage::Format_Grayscale8);
    QImage bImg(rgbs[2].data(), width, height, width, QImage::Format_Grayscale8);
    ui->wR->setImg(rImg.copy());
    ui->wG->setImg(gImg.copy());
    ui->wB->setImg(bImg.copy());

    delete[] imgChar;
    imgChar = nullptr;

}

void FromMain::on_btnSplit_2_clicked()
{
    if(m_img.isNull())
        return;
    ui->wB->setVisible(true);
    ui->wR->setVisible(true);
    ui->wG->setVisible(true);
    QVector<QImage> rgbs = imgHelper::rgbSplit(m_img);
    ui->wR->setImg(rgbs[0]);
    ui->wG->setImg(rgbs[1]);
    ui->wB->setImg(rgbs[2]);
}

void FromMain::on_btnYuvToRgb_clicked()
{
     QFile File("lena_256x256_yuv420.yuv");
     if(!File.exists())
         return;
     if(!File.open(QIODevice::ReadOnly))
         return;
     QByteArray dd = File.readAll();
     File.close();
     int width = 256;
     int height = 256;
    QVector<unsigned char> img = imgHelper::yuv420pToRGB24(reinterpret_cast<unsigned char*>(dd.data()),width,height);
    QImage rgbImg(img.data(), width, height, width*3, QImage::Format_RGB888);
    m_img =rgbImg.copy();
    ui->wSrc->setImg(m_img);
}

void FromMain::on_btnRgbToYuv_clicked()
{
    if(m_img.isNull())
        return;
    int height = m_img.height();
    int width = m_img.width();
    m_img = m_img.convertToFormat(QImage::Format_RGB888);
    //1.转成成unsigned char*
    unsigned char * imgChar = new unsigned char[height*width*3];
    std::fill_n(imgChar,height*width*3,0);
    for(int i = 0;i<height;i++)
    {
        memcpy(imgChar+i*width*3,m_img.scanLine(i),width*3);
    }

    QVector<unsigned char> img = imgHelper::rgb24ToYUV420p(imgChar,width,height);

    QFile::remove("cie1931_500x500.yuv");

    QFile yuvFile("cie1931_500x500.yuv");
    if(!yuvFile.open(QIODevice::WriteOnly))
        return;
    yuvFile.write(reinterpret_cast<char*>(img.data()),img.size());
    yuvFile.close();
    delete imgChar;
}

void FromMain::on_btnYuvSplit_clicked()
{
    if(m_img.isNull())
        return;
    ui->wB->setVisible(true);
    ui->wR->setVisible(true);
    ui->wG->setVisible(true);
    // 1.rgb转yuv
    int height = m_img.height();
    int width = m_img.width();
    m_img = m_img.convertToFormat(QImage::Format_RGB888);
    const unsigned char * imgChar = m_img.constBits();
    QVector<unsigned char> yuvimg = imgHelper::rgb24ToYUV420p(imgChar,width,height);
    // 2. 分割yuv
    QVector<QVector<unsigned char>> imgs = imgHelper::yuvSplit(reinterpret_cast<unsigned char*>(yuvimg.data()),width,height);
    QImage rImg(imgs[0].data(), width, height, width, QImage::Format_Grayscale8);
    QImage gImg(imgs[1].data(), width/2, height/2, width/2, QImage::Format_Grayscale8);
    QImage bImg(imgs[2].data(), width/2, height/2, width/2, QImage::Format_Grayscale8);
    ui->wR->setImg(rImg.copy());
    ui->wG->setImg(gImg.copy());
    ui->wB->setImg(bImg.copy());
}

void FromMain::on_btnRgbF_clicked()
{
    if(m_img.isNull())
        return;
    int height = m_img.height();
    int width = m_img.width();
    m_img = m_img.convertToFormat(QImage::Format_RGB888);
    const unsigned char * imgChar = m_img.constBits();
    //分割数据
    QVector<QVector<unsigned char>> rgbImgs = imgHelper::rgbSplit(imgChar,width,height);
    //保存数据
    imgHelper::saveChannelsToFiles(rgbImgs,width,height);
}

void FromMain::on_btnYuvF_clicked()
{
    if(m_img.isNull())
        return;
    // 1.rgb转yuv
    int height = m_img.height();
    int width = m_img.width();
    m_img = m_img.convertToFormat(QImage::Format_RGB888);
    const unsigned char * imgChar = m_img.constBits();
    QVector<unsigned char> yuvimg = imgHelper::rgb24ToYUV420p(imgChar,width,height);
    // 2. 分割yuv
    QVector<QVector<unsigned char>> yuvimgs = imgHelper::yuvSplit(reinterpret_cast<unsigned char*>(yuvimg.data()),width,height);
    //保存数据
    imgHelper::saveChannelsToFiles(yuvimgs,width,height,"yuv");
}

void FromMain::on_btnSelectFile_clicked()
{
    m_filePath = QFileDialog::getOpenFileName(this,"Select File",".","FILE(*)");
    if(m_filePath.isEmpty())
        return;
    ui->wB->setVisible(false);
    ui->wR->setVisible(false);
    ui->wG->setVisible(false);
    showImg(m_filePath);
}

void FromMain::on_btnReload_clicked()
{
    int width = ui->txtWidth->text().toInt();
    int height = ui->txtHeight->text().toInt();
    QString format = ui->comboBox->currentText();
    selectFormt(m_filePath,width,height,format);
    //ui->widgetSet->setVisible(true);
}

void FromMain::dragEnterEvent(QDragEnterEvent *event)
{
    if(event->mimeData()->hasUrls())
    {
        event->acceptProposedAction();
    }
    else
    {
        event->ignore();
    }
}

void FromMain::dropEvent(QDropEvent *event)
{
    const QMimeData * mim = event->mimeData();
    if(mim->hasUrls())
    {
        QList<QUrl> urls = mim->urls();
        foreach (auto url, urls)
        {
            m_filePath = url.toLocalFile();
            ui->wB->setVisible(false);
            ui->wR->setVisible(false);
            ui->wG->setVisible(false);
            showImg(m_filePath);
        }
    }
}

void FromMain::on_btnYuvGray_clicked()
{
    if(m_img.isNull())
        return;
    //rgb转yuv
    int height = m_img.height();
    int width = m_img.width();
    m_img = m_img.convertToFormat(QImage::Format_RGB888);
    const unsigned char * imgChar = m_img.constBits();
    QVector<unsigned char> img = imgHelper::rgb24ToYUV420p(imgChar,width,height);
    //yuv转灰度
    QVector<unsigned char> imgGray = imgHelper::yuvToGray(img.data(),width,height);
    //yuv灰度转rgb
    QVector<unsigned char> imgGrayRgb = imgHelper::yuv420pToRGB24(imgGray.data(),width,height);
    QImage iimg (imgGrayRgb.data(),width,height,width*3,QImage::Format_RGB888);
    m_img = iimg.copy();
    ui->wSrc->setImg(m_img);
}

void FromMain::on_btnYuvYHalf_clicked()
{
    if(m_img.isNull())
        return;
    //rgb转yuv
    int height = m_img.height();
    int width = m_img.width();
    m_img = m_img.convertToFormat(QImage::Format_RGB888);
    const unsigned char * imgChar = m_img.constBits();
    QVector<unsigned char> img = imgHelper::rgb24ToYUV420p(imgChar,width,height);
    //yuv转灰度
    QVector<unsigned char> imgGray = imgHelper::yuvToYhalf(img.data(),width,height);
    //yuv灰度转rgb
    QVector<unsigned char> imgGrayRgb = imgHelper::yuv420pToRGB24(imgGray.data(),width,height);
    QImage iimg (imgGrayRgb.data(),width,height,width*3,QImage::Format_RGB888);
    m_img = iimg.copy();
    ui->wSrc->setImg(m_img);
}


void FromMain::on_btnPnsr_clicked()
{
    QByteArray imgSrcArr = imgHelper::getImgFromFile("lena_256x256_yuv420.yuv");
    QByteArray imgDelArr = imgHelper::getImgFromFile("lena_distort_256x256_yuv420p.yuv");

    const unsigned char * imgSrc = reinterpret_cast<const unsigned char*>(imgSrcArr.data());
    const unsigned char * imgDel = reinterpret_cast<const unsigned char*>(imgDelArr.data());

    qDebug()<<imgHelper::psnr(imgSrc,imgDel,256,256);
}

